#include "socketthread.h"
#include <QDebug>
#include <QThread>
#include <QByteArray>
#include <string.h>
#include "agreement/agreement.h"
#include "agreement/storage_pack.h"
#include "Qt/socketclient.h"
//#include "socketviewer.h"

//QString SocketThread::hostName="";
//quint16 SocketThread::port=0;
int SocketThreadViewer::load=0; // 重载标志

SocketThread::SocketThread(QString _objName, QObject *parent) : objName(_objName), MultiThread(parent)
{
    socket = nullptr;
}
#if 0
int SocketThread::init(const QString _hostName, const quint16 _port)
{
    //const char viewer[] = "SocketViewer";
    // 1. 创建TCP套接字对象
    socket = new QTcpSocket(this);
    socket->abort();        //取消原有连接
    // 2. 已连接、数据可读、失败信号连接
    //connect(socket, &QTcpSocket::connected, this, &SocketClient::connected);
    connect(socket, &QIODevice::readyRead, this, &SocketThread::readyRead);
    typedef void (QAbstractSocket::*QAbstractSocketErrorSignal)(QAbstractSocket::SocketError);
    connect(socket, static_cast<QAbstractSocketErrorSignal>(&QTcpSocket::error), this, &SocketThread::error);
    //3. 与服务器端建立连接
    //socket->connectToHost("39.108.72.130", 9910, QTcpSocket::ReadWrite);
    socket->connectToHost(_hostName, _port, QTcpSocket::ReadWrite);
    socket->waitForConnected();
    //4. 同步处理-等待数据可读
    //socket->waitForReadyRead();
//    socket->write(viewer, strlen(viewer));
//    socket->flush();
//    socket->waitForBytesWritten();
    return  0;
}
#endif
void SocketThread::doWork(const QString parameter)
{
    qDebug() << "local run:" + parameter;
    QString result("Done!");
    uint32_t count=0;
    while(is_run())
    {
        QThread::msleep(1000);
        //qDebug() << "run--"+QString::number(count);
        emit resultReady("run--"+QString::number(count), NULL);
        count++;
        agreement_test();
    }
    /* ... here is the expensive or blocking operation ... */
    emit resultReady(result, NULL);
    qDebug() << "client exit";
    //this->exit(0);
}

#define CACHE_SIZE   2048
//void SocketThreadViewer::vin_list_add(const char vin[])
//{
//    const uint16_t _size = sizeof(vin_list)/sizeof (vin_list[0]);
//    uint16_t index = 0;
//    for(index=0; index<_size; index++)
//    {
//        if(0==strcmp(vin, vin_list[index])) return;
//    }
//    for(index=0; index<_size; index++)
//    {
//        if('\0'==vin_list[index][0])
//        {
//            memcpy(vin_list[index], vin, strlen(vin));
//            break;
//        }
//    }
//}

//char *SocketThreadViewer::vin_list_for_each(uint16_t *_index)
//{
//    uint16_t index = *_index;
//    const int _size = sizeof (vin_list)/sizeof (vin_list[0]);

//    for(index=0; index<_size; index++)
//    {
//        if('\0'!=vin_list[index][0])
//        {
//            return vin_list[index];
//        }
//    }
//    return NULL;
//}

void SocketThreadViewer::doWork(const QString parameter)
{
    const char download[]="Download";
    // 禁止重载
    if(0!=load) return;
    load = 1;
    _busy = 1;
    qDebug() << "download run " + parameter;
    //QString result("Done!");
    uint32_t count=0;
    qint64 _size=0;
    static char jbuf[1024*5];
    char data[1024];
    char *read_buf=NULL;
    char hex[1024*5];
    //QByteArray recv; // 接收数据
    //char *recv_buf=NULL; // 接收数据
    //char msg_buf[2048];
    char caches[50][CACHE_SIZE];
    uint16_t caches_index=0;
    char *msg = NULL;
    struct device_list device;
    const struct agreement_ofp* _agree_obd=NULL;
    int _psize=0;
    int _len=0;
    int i=0;
    int print = 1;

    init(hostName, port);
    memset(jbuf, 0, sizeof (jbuf));
    memset(hex, 0, sizeof (hex));
    _agree_obd = create_agree_obd_shanghai();
    _agree_obd->init(0, (const uint8_t*)"IMEI1234567890ABCDEF", 2, "INFO");
    caches_index = 0;
    while(is_run())
    {
        QThread::msleep(1000);
#if 1
        socket->write(download, strlen(download));
        socket->flush();
        socket->waitForBytesWritten();
        //QThread::msleep(1500);
        socket->waitForReadyRead();
#endif
        qDebug() << "SocketThreadViewer while: " + QString::number(count++)+" size:"+QString::number(socket->size());
        if(socket_err) break;
        //socket->waitForReadyRead();
        if(socket->size()<=0) continue;
        read_buf=jbuf;
        memset(jbuf, 0, sizeof (jbuf));
        qDebug() << "SocketThreadViewer read count: " + QString::number(count++);
        //_size = socket->read(buf, sizeof (buf));
        //_size = socket->read(buf, sizeof (buf));
        //recv = socket->readAll();  // 读取全部数据
        //recv_buf = recv.data();
        //read_buf = recv_buf;
        //qDebug("readAll [%d], %d", recv.size(), socket->size());
        while(is_run()) // 一次性读完所有数据
        {
#if 1
            int _rsize=0;
            char _byte=0x00;
            qint64 ssize = socket->size();
            if(ssize<=0) break;
            if(socket_err) break;
            // 按字节读取一个 JSON
            _rsize=0;
            memset(jbuf, 0, sizeof (jbuf));
            for(_rsize=0; _rsize<ssize; _rsize++)
            {
                if(1!=socket->read(&_byte, 1))  // 去读 1字节
                {
                    break;
                }
                jbuf[_rsize] = _byte;
                if('\0'==_byte) break;
            }
            //QThread::msleep(300);
            memset(hex, 0, sizeof (hex));
            qDebug("SocketThreadViewer..1 read[%ld], %d, %ld", strlen(jbuf), _rsize, socket->size());
            //read_buf += _size;  // default 128
            if(0!=json_device_parse(jbuf, hex, sizeof(hex), &device, &_psize) )
            {
                continue;
            }
            //qDebug("SocketThreadViewer..2 read[%d], %d", _size, _rsize);
#else
            if((read_buf-recv_buf) > recv.size()) break;
            //socket->waitForReadyRead();
//            if(socket_err) break;
//            _size = socket->read(read_buf, 128);    // 每次读取 128 字节
            //qDebug("read[%d], %s", _size, buf);
//            if(_size<=0) break;
//            if(socket_err) break;
            memset(hex, 0, sizeof (hex));
            qDebug("SocketThreadViewer read[%d], %d", _size, read_buf-recv_buf);
            //read_buf += _size;  // default 128
            if(0!=json_device_parse(read_buf, hex, sizeof(hex), &device, &_psize) )
            {
                //read_buf += _size;  // default 128
                read_buf += strlen(read_buf)+1;
                continue;
            }
            read_buf += strlen(read_buf)+1;
            qDebug("SocketThreadViewer read[%d], %d", _size, read_buf-recv_buf);
#endif
//            memcpy(jbuf, &jbuf[strlen(jbuf)+1], 1024);
//            read_buf = &jbuf[strlen(jbuf)];
            //qDebug("hex: %s", hex);
            memset(data, 0, sizeof (data));
            i=0;
            _len=0;
            _size = strlen(hex);
            while(i<_size)
            {
    #if 1
                    while(' '==hex[i]) i++;
                    data[_len++] = ((hex2int(hex[i])&0x0F)<<4) | (hex2int(hex[i+1])&0x0F);
                    i+=2;
    #else
                sscanf(&hex[i], "%02X", &buf[_len]);
                _len++;
                i += 3;
    #endif
            }
    //        printf("buf:");
    //        for(i=0; i<_psize; i++)
    //        {
    //            printf(" %02X", buf[i]&0xFF);
    //        }
    //        printf("\n");
            //qDebug("_psize:%d, %d | %d", _psize, _len, i);
            print = 0;
            set_filter_vin("VIN123");
            //decode_server(&print, _agree_obd, (const uint8_t *)buf, _len, msg_buf, sizeof(msg_buf), &device, NULL);
            msg = caches[caches_index++];
            if(caches_index>=50) caches_index=0;
            if(0==decode_viewer(&print, _agree_obd, (const uint8_t *)data, _len, msg, CACHE_SIZE, &device))
            {
                qDebug("read VIN: %s SN:%d\n", device.VIN, device.sn);
                const struct general_pack_shanghai * _pack = (const struct general_pack_shanghai*)msg;
                //vin_list_add((char*)(_pack->VIN));
                emit resultReady(device.sn, _pack);
            }

    //        qDebug("read VIN: %s\n", device.VIN);
    //        qDebug("read hex: %s\n", hex);
    //        qDebug() << "run--"+QString::number(count);
    //        emit resultReady("run--"+QString::number(count), NULL);
    //        count++;
            QThread::msleep(50);
        }
    }
    /* ... here is the expensive or blocking operation ... */
    emit resultReady("DisConnect", NULL);
    //QThread::msleep(100);
    qDebug() << "client exit";

    load = 0;
    if(socket->isOpen()) socket->close();
    delete socket;
    socket = nullptr;
    _busy = 0;
    //this->exit(0);
}
void SocketThreadViewer::_init(const QString _hostName, const quint16 _port)
{
    const char viewer[] = "SocketViewer";
    qDebug("connect...");
    // 1. 创建TCP套接字对象
    socket = new QTcpSocket(this);
    socket->abort();        //取消原有连接
    // 2. 已连接、数据可读、失败信号连接
    //connect(socket, &QTcpSocket::connected, this, &SocketClient::connected);
    connect(socket, &QIODevice::readyRead, this, &SocketThreadViewer::readyRead);
    typedef void (QAbstractSocket::*QAbstractSocketErrorSignal)(QAbstractSocket::SocketError);
    connect(socket, static_cast<QAbstractSocketErrorSignal>(&QTcpSocket::error), this, &SocketThreadViewer::error);
    //3. 与服务器端建立连接
    //socket->connectToHost("39.108.72.130", 9910, QTcpSocket::ReadWrite);
    socket->connectToHost(_hostName, _port, QTcpSocket::ReadWrite);
    socket->waitForConnected();
    qDebug("send SocketViewer");
    //4. 同步处理-等待数据可读
    //socket->waitForReadyRead();
    socket->write(viewer, strlen(viewer));
    socket->flush();
    socket->waitForBytesWritten();
}
void SocketThreadViewer::connected()
{
    qDebug() << "SocketViewer::readyRead " << socket->readAll();
}
void SocketThreadViewer::readyRead()
{
    qDebug() << "SocketViewer::connected  successfully";
}
void SocketThreadViewer::error(QAbstractSocket::SocketError socketError)
{
    qDebug() << "SocketViewer::error " << socketError;
    socket_err = 1;
}

#include "obdii_4g.h"
void Thread_Pond::doWork(const QString parameter)
{
    int i;
    enum ssl_type ssl=SSL_RSA;
    //SocketThread *thread=NULL;
    qDebug() << "Thread_Pond run " + parameter;
    for(i=0; i<200; i++) // 创建并发线程
    {
        thread_pond[i] = new SocketThreadClient();
        thread_pond[i]->IP(hostName, port);
        OBDII_4G::set_ssl(ssl);
        //connect(viewer, SIGNAL(resultReady(const QString &result, const void* data)), this, SLOT(handleResults(const QString &result, const void* data)));
        connect(thread_pond[i], &MultiThread::resultReady, this, &Thread_Pond::handleThread);
        _controller_pond[i] = new ControllerMultiThread(thread_pond[i]);
        _controller_pond[i]->start("Client Thread..."+QString::number(i));
        QThread::msleep(100);
    }
    while(is_run())
    {
        QThread::msleep(5000);
    }
}
